#ifndef _QGAMEWIDGET_H_
#define _QGAMEWIDGET_H_

#include <OGRE/Ogre.h>
#include <OGRE/Overlay/OgreOverlaySystem.h>
#include <QtOpenGL/QGLWidget>
#include <OgreMaterialManager.h>

#include "overlay.h"
#include "statemanager.h"
#include "input.h"
#include "player.h"
#include "world.h"
#include "physicsmanager.h"
#include "obstacles.h"

/**
 * @brief The GameWidget class.
 *
 * A class that is responsible to initialise a QGLWidget and integrate an ogre render window. Scene creation is done here as well.
 */
class GameWidget : public QGLWidget
{
	Q_OBJECT

public: // interface
	/** Constructor of GameWidget
	 *
	 * @param ogreRoot: Pointer to OgreRoot
	 * @param parent: Pointer to parent Widget
	 *
	 * @throws if parent is NULL
	 */
	GameWidget(Ogre::Root* ogreRoot, QWidget* parent);

	/**
	 * @brief GetEmbeddedOgreWindow
	 * @return RenderWindow
	 */
	Ogre::RenderWindow* GetEmbeddedOgreWindow();

    /**
     * @brief Get Player
     * @return pointer to the player
     */
    Player* GetPlayer();

    /**
     * @brief Get Obstacles
     * @return pointer to the obstacles
     */
    Obstacles* GetObstacles();

    /**
     * @brief UnloadLevel
     * Unloads the current level
     */
    void UnloadLevel();
    /**
     * @brief Setup
     * @param p_Level: Integer to identify level
     * Sets up new level
     */
    void Setup(int p_Level = 1);

protected:
	/** @name Inherited from QWidget
	 */
	//@{
	virtual void update();
	virtual void paintEvent(QPaintEvent* pEvent);
	virtual void resizeEvent(QResizeEvent* rEvent);
	virtual void mousePressEvent(QMouseEvent  *event);
	//@}

private:
	/**
	 * @brief m_StateManager
	 *
	 * The StateManager manages the states of the game.
	 */
	StateManager* m_StateManager;

	/**
	 * @brief PhysicsManager
	 *
	 * The PhysicsManager handles collision
	 */
	PhysicsManager *m_PhysicsManager;

	/**
	 * @brief m_InputHandler
	 *
	 * The InputHandler manages input for this widget.
	 */
	InputHandler* m_InputHandler;

    /**
     * @brief m_OgreRoot
     * Pointer to OgreRoot
     */
    Ogre::Root* m_OgreRoot;

    /**
     * @brief m_OgreRenderWindow
     * Pointer to Render Window
     */
    Ogre::RenderWindow* m_OgreRenderWindow;

    /**
     * @brief m_OgreViewport
     * Our basic Viewport
     */
    Ogre::Viewport* m_OgreViewport;

    /**
     * @brief m_OgreSceneManager
     * The Scene Manager is created here and handed to serveral other classes
     */
    Ogre::SceneManager* m_OgreSceneManager;

//    /**
//     * @brief m_MaterialManager
//     */
//	Ogre::MaterialManager* m_MaterialManager;    ///< Material Manager

    /**
     * @brief m_ResourceGroupName
     * The Resource Group Manager is initiated here
     */
    Ogre::String m_ResourceGroupName;

//	Ogre::OverlaySystem* m_OverlaySystem;

    /**
     * @brief m_Overlay
     */
    Overlay* m_Overlay;

    /**
     * @brief m_Player
     * The Player is created here and handed to the player class and other classes.
     */
	Player* m_Player;

    /**
     * @brief m_World
     * The World is created here and handed to the world class.
     */
	World* m_World;

    /**
     * @brief m_Obstacles
     * The Obstacles is created here and handed to the obstacle class.
     */
	Obstacles* m_Obstacles;

    /**
     * @brief m_StepTimer
     * QTimer
     */
    QTimer *m_StepTimer;

	/**
     * @brief Reset
	 *
     * Resets the game within the current level
	 */
	void Reset();

    /**
     * @brief SetupResources
     * @param p_level: Integer to identify level
     *
     * Setup the resource group for the current level
     */
    void SetupResources(int p_level);

    /**
     * @brief CreateViewports
     */
	void CreateViewports();

    /**
     * @brief CreateSceneManager
     */
	void CreateSceneManager();

    /**
     * @brief CreateOverlay
     */
	void CreateOverlay();


private slots:
    /**
     * @brief UpdateGame
     */
	void UpdateGame();

}; // class

//*********************************************************************************************************************

#endif
